﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////
#include "CreateViewPortDlg.h"
#include "GmStyleSheetHelper.h"
#include "IDocument.h"
#include "IUiDocument.h"
#include "IModelView.h"
#include "IElementBasicInformation.h"
#include "QFamilyTreeWidgetUtil.h"
#include "UiCommonDialog.h"
#include "IDrawingLayoutManager.h"
#include "IDrawingViewport.h"
#include "IDrawingLayout.h"
#include "GbmpModelViewTypes.h"
#include "EnableCompileWarning_The_LAST_IncludeInCpp.h"

using namespace gcmp;

CreateViewPortDlg::CreateViewPortDlg(QWidget *parent) :
    QDialog(parent, Qt::FramelessWindowHint)
{
    m_ui.setupUi(this);
    m_ui.modelViewTree->header()->setVisible(false);
    std::wstring styleSheetStr = GmStyleSheetHelper::Instance()->GetCurrentStyleData();
    setStyleSheet(QString::fromStdWString(styleSheetStr));
    m_ui.gbmp_title->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
    m_ui.gbmp_title->setIconVisible(false);
    m_ui.gbmp_title->setMaxButtonVisible(false);
    m_ui.gbmp_title->setMinButtonVisible(false);
    m_ui.gbmp_title->setText(QString::fromStdWString(GBMP_TR(L"创建视口")));
    this->setProperty("use_gbmp_title", true);
    connect(m_ui.gbmp_title, &GmTitleBar::closeRequested, this, &CreateViewPortDlg::reject);
    connect(m_ui.gbmp_title, &GmTitleBar::moveRequested, this, &CreateViewPortDlg::onMoveRequested);

    QObject::connect(m_ui.okButton, SIGNAL(clicked()), this, SLOT(OnClickOk()));
    QObject::connect(m_ui.cancelButton, SIGNAL(clicked()), this, SLOT(OnClickCancel()));
    //UpdateModelViewsTree(pUiDoc);
}

CreateViewPortDlg::~CreateViewPortDlg()
{
}

void CreateViewPortDlg::onMoveRequested(const QPoint& cursorPos, const QPoint& offset)
{
    Q_UNUSED(cursorPos);
    move(pos() + offset);
}

QTreeWidgetItem* CreateViewPortDlg::InitViewType(const std::wstring& viewType)
{
    std::wstring typeName;
    typeName = GbmpModelViewTypeUtil::GetModelViewTypeName(viewType);

    for (int i = 0; i < m_ui.modelViewTree->topLevelItemCount(); ++i)
    {
        QTreeWidgetItem* pItemViewType = m_ui.modelViewTree->topLevelItem(i);
        if (pItemViewType)
        {
            std::wstring itemType = pItemViewType->data(0, Qt::UserRole).toString().toStdWString();
            if (itemType == typeName)
                return pItemViewType;
        }
    }

    OwnerPtr<QTreeWidgetItem> itemViewType = NEW_AS_OWNER_PTR(QTreeWidgetItem, QStringList(QString::fromStdWString(typeName)));
    itemViewType->setData(0, Qt::UserRole, QString::fromStdWString(typeName));

    QTreeWidgetItem* pTtopViewTypeItem = itemViewType.get();

    m_ui.modelViewTree->addTopLevelItem(TRANSFER_OWNERSHIP_TO_THIRD_PARTY(itemViewType));
    return pTtopViewTypeItem;
}

void CreateViewPortDlg::UpdateModelViewsTree(gcmp::IUiDocument* pUIDoc, bool isMultiViewport)
{
    ClearModelViewsItem();

    DBG_WARN_AND_RETURN_VOID_UNLESS(pUIDoc != nullptr, L"pUIDoc为空",L"GDMPLab",L"2024-03-30");

    IDocument *pDbDoc = pUIDoc->GetDbDocument();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pDbDoc != nullptr, L"pDbDoc为空",L"GDMPLab",L"2024-03-30");

    std::vector<IModelView *> modelViews = IModelView::GetAllModelViews(pDbDoc);
    auto modelViewCompare = [](const IModelView* pView1, const IModelView* pView2)
    {
        if (pView1->GetViewType() < pView2->GetViewType())
            return true;
        else
            return false;
    };
    std::stable_sort(modelViews.begin(), modelViews.end(), modelViewCompare);
    InitViewType(PlanViewType);
    InitViewType(View3DViewType);
    InitViewType(ElevationViewType);

    std::wstring errorMessage = L"";
    const IDrawingLayoutManager* pLayoutsManager = IDrawingLayoutManager::Get(pDbDoc, &errorMessage);
    if (!pLayoutsManager)
    {
        if (errorMessage == L"")
            errorMessage = L"获取图纸管理器失败。";

        UiCommonDialog::ShowMessageBox(GBMP_TR(L"创建视口失败"), GBMP_TR(errorMessage), (int)(UiCommonDialog::ButtonType::OK));
        return;
    }

    std::vector<IDrawingLayout*> layouts = pLayoutsManager->GetAllLayouts();
    std::vector<ElementId> currentModelViewIds;
    FOR_EACH(layout, layouts)
    {
        std::vector<IDrawingViewport*> viewports = layout->GetAllViewports();
        FOR_EACH(viewport, viewports)
        {
            currentModelViewIds.push_back(viewport->GetModelViewId());
        }
    }

    for (int i = 0; i < (int)modelViews.size(); ++i)
    {
        IModelView* pModelView = modelViews[i];
        DBG_WARN_AND_CONTINUE_UNLESS(pModelView != nullptr, L"pModelView为空",L"GDMPLab",L"2024-03-30");

        std::wstring strName = pModelView->GetBasicInformation()->GetName();
        if (pModelView->GetViewType() == BuiltInViewType::Drawing)
        {
            continue;
        }

        const IModelView* pConstModelView = pModelView;
        if (pConstModelView->GetViewportModelViewComponent())
        {
            continue;
        }
        QTreeWidgetItem * parentItem = InitViewType(pModelView->GetUserDataId());

        if (parentItem)
        {
            OwnerPtr<QTreeWidgetItem> childItemView = NEW_AS_OWNER_PTR(QTreeWidgetItem, parentItem, QStringList(QString::fromStdWString(strName)));
            childItemView->setData(0, MODEL_VIEW_USER_DATA_ROLE, pModelView->GetBasicInformation()->GetElementId().AsInt64());
            auto iter = std::find(currentModelViewIds.begin(), currentModelViewIds.end(), pModelView->GetBasicInformation()->GetElementId());
            if (iter != currentModelViewIds.end())
            {
                if (!isMultiViewport)
                {
                    childItemView->setDisabled(true);
                    childItemView->setSelected(false);
                }
            }
            parentItem->addChild(TRANSFER_OWNERSHIP_TO_THIRD_PARTY(childItemView));
        }
    }
    ExpandAllModelViewItems();
}

void CreateViewPortDlg::ExpandAllModelViewItems()
{
    for (int i = 0; i < m_ui.modelViewTree->topLevelItemCount(); ++i)
    {
        QTreeWidgetItem *pTopLevelItem = m_ui.modelViewTree->topLevelItem(i);
        if (pTopLevelItem->data(0, Qt::UserRole).isValid())
        {
            pTopLevelItem->setExpanded(true);
        }
    }
}

void CreateViewPortDlg::ClearModelViewsItem()
{
    for (int i = 0; i < m_ui.modelViewTree->topLevelItemCount();)
    {
        QTreeWidgetItem *pTopLevelItem = m_ui.modelViewTree->topLevelItem(i);
        if (pTopLevelItem->data(0, Qt::UserRole).isValid())
        {
            OwnerPtr<QTreeWidgetItem> opTopLevelItem(m_ui.modelViewTree->takeTopLevelItem(i));
        }
        else
        {
            ++i;
        }
    }
}

QTreeWidgetItem* CreateViewPortDlg::GetSelectedItem()
{
    QTreeWidgetItem* pSelectedItem = m_ui.modelViewTree->currentItem();
    if (pSelectedItem)
    {
        return pSelectedItem;
    }
    return nullptr;
}

void CreateViewPortDlg::OnClickOk()
{
    if (!GetSelectedItem() || GetSelectedItem()->data(0, MODEL_VIEW_USER_DATA_ROLE).toLongLong() == 0)
    {
        UiCommonDialog::ShowMessageBox(GBMP_TR(L"选择视图"), GBMP_TR(L"你的选择非法，请重新选择！"), (int)(UiCommonDialog::ButtonType::OK));
    }
    else
    {
        QDialog::accept();
    }
}

void CreateViewPortDlg::OnClickCancel()
{
    QDialog::reject();
}
